package com.ruoyi.system.service.impl;

import com.ruoyi.system.service.IJisuangongshiService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class JisuangongshiService implements IJisuangongshiService {

    //月津贴金额变化类，{变化时间：变化前金额}
    private static List<ChangeTimeMoney> changeTimeMoneyList = new ArrayList<>();

    //现在月津贴
    private static double nowMonthMoney = 600.0;

    //初始化月津贴金额变化类，需手动添加变化
    static {
        changeTimeMoneyList.add(new ChangeTimeMoney(LocalDateTime.of(2001, 1, 1, 0, 0, 0), 100.0));
    }

    /**
     * 正常发放
     * @param piciEnd 批次结束时间
     * @param shangcifafangshijian 专家在这次申报之前的最近一次发放时间
     * @return
     */
    @Override
    public List<Double> zhengchangfafang(LocalDateTime piciStart, LocalDateTime piciEnd, LocalDateTime shangcifafangshijian) {

        double totalMoney = 0.0;
        //寻找上次发放时间在月津贴变化的标识
        //记录此次变化前一次变化时间，用来计算两个时间之间的时间差
        LocalDateTime lastChangeTime = changeTimeMoneyList.get(changeTimeMoneyList.size() - 1).time;
        totalMoney += jisuan(changeTimeMoneyList, shangcifafangshijian, piciEnd);
        //计算未发批次的津贴额。此部分代码一般不会执行
        if (shangcifafangshijian.isBefore(lastChangeTime))
            totalMoney += ( (piciEnd.getYear() * 12 + piciEnd.getMonthValue()) -
                    (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * nowMonthMoney;
        else
            totalMoney += ( (piciEnd.getYear() * 12 + piciEnd.getMonthValue()) -
                    (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * nowMonthMoney;
        return getDoubles(piciStart, piciEnd, totalMoney);
    }

    /**
     * 专家最新状态变化是停发，且停发申报时间在专家中心制定拨款计划的前后
     * 1.停发申报时间在专家中心制定拨款计划之前，则发放津贴金额 = 停发批次的月金额 * （停发时间 - 专家在这次申报之前的最近一次发放时间 + 1）；
     * 2.停发申报时间在专家中心制定拨款计划之后，则发放津贴金额 = 0；
     *
     * @param tingfashijian 专家停发时间
     * @param jiezhishijian 专家中心制定拨款计划时间
     * @param shangcifafangshijian 专家上次发放时间
     */
    @Override
    public List<Double> tingfafafang(LocalDateTime piciStart, LocalDateTime tingfashijian, LocalDateTime jiezhishijian, LocalDateTime shangcifafangshijian) {

        double totalMoney = 0.0;
        //寻找上次发放时间在月津贴变化的标识
        int i = 0;
        //记录此次变化前一次变化时间，用来计算两个时间之间的时间差
        LocalDateTime lastChangeTime = changeTimeMoneyList.get(0).time;
        for (ChangeTimeMoney changeTimeMoney : changeTimeMoneyList) {
            //i==1，表示已经找到上次发放在哪个月津贴额变化之前。然后计算几次月津贴额变化时间段的津贴总额
            if (i == 1 && tingfashijian.isAfter(changeTimeMoney.time)){
                totalMoney += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
                        (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * changeTimeMoney.money;
                lastChangeTime = changeTimeMoney.time;
            }//计算上次发放到，离上次发放最近的一次变化之间的津贴总额
            else if (shangcifafangshijian.isBefore(changeTimeMoney.time)) {
                i = 1;
                totalMoney += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
                        (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * changeTimeMoney.money;
                lastChangeTime = changeTimeMoney.time;
            }
        }
        if (shangcifafangshijian.isBefore(lastChangeTime))
            totalMoney += ( (tingfashijian.getYear() * 12 + tingfashijian.getMonthValue()) -
                    (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * nowMonthMoney;
        else
            totalMoney += ( (tingfashijian.getYear() * 12 + tingfashijian.getMonthValue()) -
                    (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * nowMonthMoney;
        if (totalMoney < 0)
            totalMoney = 0.0;

        return getDoubles(piciStart, tingfashijian, totalMoney);
    }

    /**
     * 专家最新状态变化是补发，且补发时间在专家中心制定拨款计划之前后
     * 1.补发时间在专家中心制定拨款计划之前，则发放津贴金额 = （批次结束时间 - 专家在这次申报之前的最近一次发放时间 + 1） * 每月津贴；
     * 2.补发时间在专家中心制定拨款计划之后，则发放津贴金额 = 0；
     *
     * @param piciEnd 批次结束时间
     * @param shangcifafangshijian 专家在这次申报之前的最近一次发放时间
     * @param jisuanshijian 专家中心制定拨款计划时间
     */
    @Override
    public List<Double> bufafafang(LocalDateTime biangengshijian, LocalDateTime piciStart, LocalDateTime piciEnd, LocalDateTime jisuanshijian, LocalDateTime shangcifafangshijian) {
        double totalMoney = 0.0;
        if (shangcifafangshijian.isBefore(jisuanshijian)) {
            //寻找上次发放时间在月津贴变化的标识

            //记录此次变化前一次变化时间，用来计算两个时间之间的时间差
            LocalDateTime lastChangeTime = changeTimeMoneyList.get(changeTimeMoneyList.size() - 1).time;
            //计算未发批次的津贴额。此部分代码一般不会执行
            totalMoney += jisuan(changeTimeMoneyList, shangcifafangshijian, piciEnd);
//            for (ChangeTimeMoney changeTimeMoney : changeTimeMoneyList) {
//                //i==1，表示已经找到上次发放在哪个月津贴额变化之前。然后计算几次月津贴额变化时间段的津贴总额
//                if (i == 1){
//                    totalMoney += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
//                            (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * changeTimeMoney.money;
//                    lastChangeTime = changeTimeMoney.time;
//                }//计算上次发放到，离上次发放最近的一次变化之间的津贴总额
//                else if (piciEnd.isBefore(changeTimeMoney.time)) {
//                    i = 1;
//                    totalMoney += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
//                            (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * changeTimeMoney.money;
//                    lastChangeTime = changeTimeMoney.time;
//                }
//            }
            if (shangcifafangshijian.isBefore(lastChangeTime))
                totalMoney += ( (piciEnd.getYear() * 12 + piciEnd.getMonthValue()) -
                        (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * nowMonthMoney;
            else
                totalMoney += ( (piciEnd.getYear() * 12 + piciEnd.getMonthValue()) -
                        (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * nowMonthMoney;
        }
        if (totalMoney < 0)
            totalMoney = 0.0;
        return getDoubles(piciStart, piciEnd, totalMoney);
    }

    /**
     * 返回总金额和补发金额结果
     * @param piciStart 批次开始时间
     * @param end 批次结束时间或停发时间
     * @param totalMoney 津贴总金额
     * @return 返回总金额和补发金额结果List
     */
    private List<Double> getDoubles(LocalDateTime piciStart, LocalDateTime end, double totalMoney) {

        List<Double> zongjineAndBufajine = new ArrayList<>();
        double bufajine = totalMoney - ( (end.getYear() * 12 + end.getMonthValue() + 1) -
                (piciStart.getYear() * 12 + piciStart.getMonthValue()) ) * nowMonthMoney;
        //如果end在picistart之前，说明补发金额为
        if (end.isBefore(piciStart))
            bufajine = totalMoney;
        else if (bufajine < 0)
            bufajine = 0;

        zongjineAndBufajine.add(totalMoney);
        zongjineAndBufajine.add(bufajine);
        return zongjineAndBufajine;
    }


    /**
     * 计算上次发放时间到最近一次每月津贴变化时间段内津贴总额
     * @param changeTimeMoneyList 每月津贴变化列表
     * @param shangcifafangshijian 上次发放时间
     * @param endTime
     * @return
     */
    private double jisuan(List<ChangeTimeMoney> changeTimeMoneyList, LocalDateTime shangcifafangshijian, LocalDateTime endTime) {
        double result = 0.0;//上次发放时间到最近一次每月津贴变化时间的总金额
        int i = 0;
        LocalDateTime lastChangeTime = changeTimeMoneyList.get(0).time;
        for (ChangeTimeMoney changeTimeMoney : changeTimeMoneyList) {
            //i==1，表示已经找到上次发放在哪个月津贴额变化之前。然后计算几次月津贴额变化时间段的津贴总额
            if (i == 1 && endTime.isAfter(changeTimeMoney.time)){
                result += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
                        (lastChangeTime.getYear() * 12 + lastChangeTime.getMonthValue()) ) * changeTimeMoney.money;
                lastChangeTime = changeTimeMoney.time;
            }//计算上次发放后到离上次发放最近的一次变化之间的津贴总额
            else if (shangcifafangshijian.isBefore(changeTimeMoney.time)) {
                i = 1;
                result += ( (changeTimeMoney.time.getYear() * 12 + changeTimeMoney.time.getMonthValue()) -
                        (shangcifafangshijian.getYear() * 12 + shangcifafangshijian.getMonthValue()) ) * changeTimeMoney.money;
                lastChangeTime = changeTimeMoney.time;
            }
        }
        return result;
    }
    //月津贴变化类
    private static class ChangeTimeMoney {
        private LocalDateTime time;//变化时间

        private double money;//变化前津贴

        public ChangeTimeMoney(LocalDateTime time, double money) {
            this.time = time;
            this.money = money;
        }
    }
}
